#include "RayTracer.h"

const float PI = 3.1415926535;
bool done = false;


//Values for storing the rendering rectangle
int topX = width; 
int topY = height;
int bottomX = 0;
int bottomY = 0;
int tempTopX, tempTopY;

int counter = 0;
int x = 0;
int y = 0;


int currentRow = 0;

RayTracer::RayTracer() {}

RayTracer::~RayTracer() {
	delete scene;
}

void RayTracer::init(Scene* s) {
	scene = s;
	currentRow = bottomY;
}

//idle function for GLUT - contains the scene description
void RayTracer::idle(vector<vector<Vector3> >& image) {
	if (done == true) {
		//return;
	}
	image.clear();
	image.resize(width);
	for (int i = 0; i < width; i++) {
		image[i].resize(height);
	}
	
	float FOV = 45;
	float cameraToPlane = 0.1;
	float xRes = 270;
	float yRes = 270;
	
	float height2 = tan((FOV/2)*PI/180)*cameraToPlane; //height/2
	float width2 = height2*(xRes/yRes); //width/2
	
	Vector3 N = scene->cameraLookAt - scene->cameraLocation;
	N.normalize();
	
	Vector3 projN(N.x, N.y, N.z);
	
	Vector3 rightVector = Vector3::crossProduct(projN, Vector3(0, 0, 1));
	Vector3 upVector = Vector3::crossProduct(projN, rightVector);
	
	Vector3 centerPoint = scene->cameraLocation + N*cameraToPlane;
	
	float pixelWidth = (2*width2)/xRes;
	float pixelHeight = (2*height2)/yRes;
	
	done = true;
	
	float percent = 0;
	int last = 0;
	bool alias = false;

	QImage myImage(width, height, QImage::Format_RGB32);
	QRgb value;
	
	//Ray Tracing
	for (int i = -height/2; i < height/2; i++) {
		for (int j = -width/2; j < width/2; j++) {
			if (alias) {
				/*Vector3 pixelPoint1 = centerPoint + upVector*(i*pixelHeight - pixelHeight/3) + rightVector*(j*pixelWidth - pixelHeight/3);
				Vector3 pixelPoint2 = centerPoint + upVector*(i*pixelHeight - 2*pixelHeight/3) + rightVector*(j*pixelWidth - pixelHeight/3);
				Vector3 pixelPoint3 = centerPoint + upVector*(i*pixelHeight - pixelHeight/3) + rightVector*(j*pixelWidth - 2*pixelHeight/3);
				Vector3 pixelPoint4 = centerPoint + upVector*(i*pixelHeight - 2*pixelHeight/3) + rightVector*(j*pixelWidth - 2*pixelHeight/3);
				
				
				Vector3 dir1 = pixelPoint1 - s.cameraLocation;
				Vector3 dir2 = pixelPoint2 - s.cameraLocation;
				Vector3 dir3 = pixelPoint3 - s.cameraLocation;
				Vector3 dir4 = pixelPoint4 - s.cameraLocation;
				
				dir1.normalize();
				dir2.normalize();
				dir3.normalize();
				dir4.normalize();
				
				Ray r1(s.cameraLocation, dir1, s);
				Color c1 = r1.trace();
				c1 = c1*0.25;
				
				Ray r2(s.cameraLocation, dir2, s);
				Color c2 = r2.trace();
				c2 = c2*0.25;
				
				Ray r3(s.cameraLocation, dir3, s);
				Color c3 = r3.trace();
				c3 = c3*0.25;
				
				Ray r4(s.cameraLocation, dir4, s);
				Color c4 = r4.trace();
				c4 = c4*0.25;
				
				Color c = c1 + c2 + c3 + c4;
				
				c.boundColor();
				
				//cout << "C: " << c << endl;
				
				//pixels[j+(width/2)][i+(height/2)][0] = c.r; //Red
				//pixels[j+(width/2)][i+(height/2)][1] = c.g; //Green
				//pixels[j+(width/2)][i+(height/2)][2] = c.b; //Blue
				//pixels[j+(width/2)][i+(height/2)][3] = c.a; //Alpha*/
			}
			else {
				Vector3 pixelPoint = centerPoint + upVector*i*pixelHeight + rightVector*j*pixelWidth;
				Vector3 dir = pixelPoint - scene->cameraLocation;
				dir.normalize();
				
				Ray r(scene->cameraLocation, dir, *scene);
				Color c = r.trace();
				c.boundColor();
				
				//pixels[j+(width/2)][i+(height/2)][0] = c.r; //Red
				//pixels[j+(width/2)][i+(height/2)][1] = c.g; //Green
				//pixels[j+(width/2)][i+(height/2)][2] = c.b; //Blue
				//pixels[j+(width/2)][i+(height/2)][3] = c.a; //Alpha

				image[j+(width/2)][i+(height/2)].x = c.r; //Red
				image[j+(width/2)][i+(height/2)].y = c.g; //Green
				image[j+(width/2)][i+(height/2)].z = c.b; //Blue
				//pixels[j+(width/2)][i+(height/2)][3] = c.a; //Alpha
			}
			
			percent++;
		}
		if (((int)((percent/((float)xRes * (float)yRes))*100)) > last) {
			cout << (percent/((float)xRes * (float)yRes))*100 << " percent" << endl;
			last = (int)((percent/((float)xRes * (float)yRes))*100);
		}
	}
}